/**
 * Copyright (c) 2014.
 * Private license for beyondts.
 * Contact beyondts for using, beyondts999@163.com
 */
package net.beyondts.mplug;

import net.beyondts.mplug.utils.Transformer;
import org.apache.commons.lang3.reflect.ConstructorUtils;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * Project: beyondts-basic<br/>
 * Description: Class loader to load plugins, one loader for one plugin.<br/>
 * Created at: 2014年8月16日<br/>
 * Owned by beyondts.
 * 
 * @author blazecrystal
 *
 * @version 1.0.0
 */
public class PluginLoader extends URLClassLoader {

	/**
	 * 构造函数.
	 *
	 */
	public PluginLoader() {
		super(new URL[0], ClassLoader.getSystemClassLoader());
	}

	public PluginLoader(ClassLoader parent) {
        super(new URL[0], parent);
    }

	/**
	 * 把jar文件路径转为URL，供读取.
	 * 
	 * @param path {@link String} jar文件绝对路径
	 * @return {@link URL} 转后的URL数组
	 * @throws IOException jar文件路径不正确
	 */
	private URL toURL(String path) throws IOException {
		return new URL("file:" + Transformer.toLocalFilePath(path));
	}

	/**
	 * 加载指定的jar包.
	 * 
	 * @param path {@link String} jar文件绝对路径
	 * @throws IOException jar文件路径不正确
	 */
	public void add(String path) throws IOException {
		super.addURL(toURL(path));
	}

    /**
     * 卸载该Classloader加载的jar. 需要jdk1.7以上版本
     * @throws IOException
     */
	public void close() throws IOException {
        super.close();
    }



	/**
	 * 使用默认构造方法创建指定类的实例.
	 * 
	 * @param className {@link String} 类全名
	 * @return {@link Object} 创建的类的实例
	 * @throws ClassNotFoundException 类未找到
	 * @throws NoSuchMethodException 没有此构造方法
	 * @throws IllegalAccessException 非法入口
	 * @throws InvocationTargetException 调用目标异常
	 * @throws InstantiationException 实例化异常
	 */
	public Object createInstance(String className)
			throws ClassNotFoundException, NoSuchMethodException,
			IllegalAccessException, InvocationTargetException,
			InstantiationException {
		Class<?> clazz = this.loadClass(className);
		return ConstructorUtils.invokeConstructor(clazz, null);
	}

	/**
	 * 创建指定类的实例.
	 * 
	 * @param className {@link String} 类全名
	 * @param constructorArgs {@link Object}[] 构造方法的参数
	 * @return {@link Object} 创建的类的实例
	 * @throws ClassNotFoundException 类未找到
	 * @throws NoSuchMethodException 没有此构造方法
	 * @throws IllegalAccessException 非法入口
	 * @throws InvocationTargetException 调用目标异常
	 * @throws InstantiationException 实例化异常
	 */
	public Object createInstance(String className, Object... constructorArgs)
			throws ClassNotFoundException, NoSuchMethodException,
			IllegalAccessException, InvocationTargetException,
			InstantiationException {
		Class<?> clazz = this.loadClass(className);
		return ConstructorUtils.invokeConstructor(clazz, constructorArgs);
	}

	/**
	 * 创建指定类的实例.
	 * 
	 * @param className {@link String} 类全名
	 * @param constructorArgs {@link Object}[] 构造方法的参数
	 * @param argTypes {@link Class}&lt;?&gt;[] 构造方法参数的类型，与参数对应
	 * @return {@link Object} 创建的类的实例
	 * @throws ClassNotFoundException 类未找到
	 * @throws NoSuchMethodException 没有此构造方法
	 * @throws IllegalAccessException 非法入口
	 * @throws InvocationTargetException 调用目标异常
	 * @throws InstantiationException 实例化异常
	 */
	public Object createInstance(String className, Object[] constructorArgs,
			Class<?>[] argTypes) throws ClassNotFoundException,
			NoSuchMethodException, IllegalAccessException,
			InvocationTargetException, InstantiationException {
		Class<?> clazz = this.loadClass(className);
		return ConstructorUtils.invokeConstructor(clazz, constructorArgs,
				argTypes);
	}

}
